<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        // super
        // 可以作为函数去使用
        // 代表父类的构造函数，只能用在子类的构造方法中，用在其他地方会报错
        // super虽然代表了父类的构造方法，但是内部的this还是指向子类的实例
        class Person {
            constructor(name, sex) {
                this.name = name;
                this.sex = sex;
                // 每次new都会新建一份
                this.say = function() {
                    console.log('say');
                };
                console.log(this);
            };
            // 共享
            speak() {
                console.log('speak');
                console.log(this);
            }
            static speak() {
                console.log(this);
            }
        }
        class Doctor extends Person {
            constructor(name, sex, feature) {
                // super代表父类的构造方法
                super(name, sex)
                this.feature = feature
            };
            // 同名覆盖
            speak() {
                console.log('doctor');
            }
        }
        // this指向Person
        // new Person();
        // this指向Doctor
        // new Doctor();

        // 2、作为对象使用
        // 2.1在构造方法中使用或者一般方法中使用，代表父类的原型对象Person.prototype
        // 所以定义在父类实例上的方法或属性，是无法通过super调用的
        // 通过super调用父类的方法时，方法内部的this指向当前子类的实例
        class Programmer extends Person {
            constructor(name, sex, feature) {
                // super代表父类的构造方法
                super(name, sex)
                super.speak();
                this.feature = feature
            };
            // 同名覆盖
            speak() {
                console.log('doctor');
            }
        }
        // new Programmer();
        // 不希望父类的方法被覆盖掉
        class Teacher extends Person {
            constructor(name, sex, feature) {
                super(name, sex)
                this.feature = feature
            };
            // 同名覆盖
            speak() {
                // 先调用父类的方法
                super.speak();
                console.log('Teacher');
            }
        }
        const teacher = new Teacher();
        teacher.speak();
        // 2.2、静态方法中指向父类,而不是父类的原型对象
        // 通过super调用父类的方法时，方法内部的this指向当前的子类，而不是子类的实例
        class Nurse extends Person {
            constructor(name, sex, feature) {
                super(name, sex)
                this.feature = feature
            };
            // 同名覆盖
            speak() {
                console.log('Nurse');
            }
            static speak() {
                // this指向子类
                super.speak()
                console.log(this);
            }
        }
        Nurse.speak();
        // 3、注意事项
        // 使用super的时候，必须显式的指定作为函数还是作为对象使用，否则会报错
    </script>
</body>

</html>